package org.aspencloud.widgets;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.aspencloud.widgets.cdatepicker.CDatepicker;
import org.aspencloud.widgets.cdatepicker.CDatepickerCombo;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;


/**
 * This class provides access to the the public constants provided
 * by AspenCloud Widgets (ACW).  This class is analogous to the SWT class
 * of the Standard Widget Toolkit (SWT) and has been created separately
 * to avoid collision.
 * <p>
 * Note that, unlike the SWT class, these constants apply for all platforms
 * (upon which ACW has been tested) because all widgets in ACW are 
 * custom widgets.
 * </p>
 */
public class ACW {
	
	/**
	 * true if the platform is carbon, false otherwise
	 */
	public static final boolean carbon = "carbon".equals(SWT.getPlatform());
	/**
	 * true if the platform is gtk, false otherwise
	 */
	public static final boolean gtk = "gtk".equals(SWT.getPlatform());
	/**
	 * true if the platform is win32, false otherwise
	 */
	public static final boolean win32 = "win32".equals(SWT.getPlatform());
	
	/**
	 * Style constant indicating no style (value is 0).
	 * <p><b>Used By:</b><ul>
	 * <li><code>All</code></li>
	 * </ul></p>
	 */
	public static final int NONE				= 0;

	/**
	 * Style constant requesting a border.  This value will be converted to its
	 * SWT equivalent and passed to the SWT super (value is 1&lt;&lt;0).
	 * <p><b>Used By:</b><ul>
	 * <li><code>All</code></li>
	 * </ul></p>
	 * @see SWT#BORDER
	 */
	public static final int BORDER			= 1 << 0;

	/**
	 * Style constant for drop down combo behavior (value is 1&lt;&lt;1).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * <li><code>CDatepickerCombo</code></li>
	 * <li><code>CNumPadCombo</code></li>
	 * </ul></p>
	 */
	public static final int DROP_DOWN 		= 1 << 1;

	/**
	 * Style constant for showing a short date format (value is 1&lt;&lt;2).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * <li><code>CDatepickerCombo</code></li>
	 * </ul></p>
	 * @see CDatepicker#setFormat(int)
	 * @see CDatepickerCombo#setFormat(int)
	 */
	public static final int DATE_SHORT		= 1 << 2;

	/**
	 * Style constant for showing a medium date format (value is 1&lt;&lt;3).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * <li><code>CDatepickerCombo</code></li>
	 * </ul></p>
	 * @see CDatepicker#setFormat(int)
	 * @see CDatepickerCombo#setFormat(int)
	 */
	public static final int DATE_MEDIUM		= 1 << 3;

	/**
	 * Style constant for showing a long date format (value is 1&lt;&lt;4).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * <li><code>CDatepickerCombo</code></li>
	 * </ul></p>
	 * @see CDatepicker#setFormat(int)
	 * @see CDatepickerCombo#setFormat(int)
	 */
	public static final int DATE_LONG		= 1 << 4;

	/**
	 * Style constant for showing a custom date format by setting the pattern (value is 1&lt;&lt;5).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * <li><code>CDatepickerCombo</code></li>
	 * </ul></p>
	 * @see CDatepicker#setFormat(int)
	 * @see CDatepickerCombo#setFormat(String)
	 */
	public static final int DATE_CUSTOM		= 1 << 5;

	/**
	 * Style constant for showing a short time format (value is 1&lt;&lt;6).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * <li><code>CDatepickerCombo</code></li>
	 * </ul></p>
	 * @see CDatepicker#setFormat(int)
	 * @see CDatepickerCombo#setFormat(int)
	 */
	public static final int TIME_SHORT		= 1 << 6;

	/**
	 * Style constant for showing a medium time format (value is 1&lt;&lt;7).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * <li><code>CDatepickerCombo</code></li>
	 * </ul></p>
	 * @see CDatepicker#setFormat(int)
	 * @see CDatepickerCombo#setFormat(int)
	 */
	public static final int TIME_MEDIUM		= 1 << 7;

	/**
	 * Style constant for showing a custom time format by setting the pattern (value is 1&lt;&lt;8).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * <li><code>CDatepickerCombo</code></li>
	 * </ul></p>
	 * @see CDatepicker#setFormat(int)
	 * @see CDatepickerCombo#setFormat(String)
	 */
	public static final int TIME_CUSTOM		= 1 << 8;

	/**
	 * Style constant to set the footer visible (value is 1&lt;&lt;9).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * </ul></p>
	 * @see CDatepicker#setFooterVisible(boolean)
	 */
	public static final int FOOTER			= 1 << 9;

	/**
	 * Style constant for a DropCombo whose button is always visible (value is 1&lt;&lt;10).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * </ul></p>
	 * @see #BUTTON_AUTO
	 * @see #BUTTON_MANUAL
	 * @see #BUTTON_NEVER
	 * @see DropCombo#setButtonVisibility(int)
	 */
	public static final int BUTTON_ALWAYS	= 1 << 10;

	/**
	 * Style constant for a DropCombo whose button is automatically set to be
	 * visible or not depending on its focus state (value is 1&lt;&lt;11).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * </ul></p>
	 * @see #BUTTON_AUTO
	 * @see #BUTTON_MANUAL
	 * @see #BUTTON_NEVER
	 * @see DropCombo#setButtonVisibility(int)
	 */
	public static final int BUTTON_AUTO		= 1 << 11;

	/**
	 * Style constant for a DropCombo whose button is never visible (value is 1&lt;&lt;12).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * </ul></p>
	 * @see #BUTTON_ALWAYS
	 * @see #BUTTON_AUTO
	 * @see #BUTTON_NEVER
	 * @see DropCombo#setButtonVisibility(int)
	 */
	public static final int BUTTON_MANUAL	= 1 << 12;

	/**
	 * Style constant for a DropCombo whose button is never visible.
	 * The difference between this and BUTTON_MANUAL is that the drop contents
	 * are never created (value is 1&lt;&lt;13).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * </ul></p>
	 * @see #BUTTON_ALWAYS
	 * @see #BUTTON_AUTO
	 * @see #BUTTON_MANUAL
	 * @see DropCombo#setButtonVisibility(int)
	 */
	public static final int BUTTON_NEVER 	= 1 << 13;

	/**
	 * Style constant for a DropCombo with its button to the Left of the text (value is 1&lt;&lt;14).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * </ul></p>
	 * @see #BUTTON_RIGHT
	 */
	public static final int BUTTON_LEFT	 	= 1 << 14;

	/**
	 * Style constant for a DropCombo with its button to the right of the text (value is 1&lt;&lt;15).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * </ul></p>
	 * @see #BUTTON_LEFT
	 */
	public static final int BUTTON_RIGHT 	= 1 << 15;
	
	/**
	 * Style constant for left aligning the text of a DropCombo (value is 1&lt;&lt;16).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * </ul></p>
	 * @see #TEXT_RIGHT
	 */
	public static final int TEXT_LEFT	 	= 1 << 16;

	/**
	 * Style constant for right aligning the text of a DropCombo (value is 1&lt;&lt;17).
	 * <p><b>Used By:</b><ul>
	 * <li><code>DropCombo</code></li>
	 * </ul></p>
	 * @see #TEXT_LEFT
	 */
	public static final int TEXT_RIGHT 		= 1 << 17;

	/**
	 * Style constant indicating that the seconds hand is NOT to be used
	 * on the CDatepicker's Clock (value is 1&lt;&lt;18).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepicker</code></li>
	 * </ul></p>
	 */
	public static final int SECONDS_OFF 		= 1 << 18;

	/**
	 * Style constant indicating that the TAB key should be used to traverse
	 * the CDatepickerCombo's fields (value is 1&lt;&lt;19).
	 * <p><b>Used By:</b><ul>
	 * <li><code>CDatepickerCombo</code></li>
	 * </ul></p>
	 */
	public static final int TAB_STOPS 		= 1 << 19;

	/**
	 * A recursive utility function used to find every child control of a composite,
	 * including the children of children.<br/>
	 * NOTE: This method will <b>NOT</b> return disposed children.
	 * @param c the composite to start from
	 * @return all the children and grandchildren of the given composite
	 */
	public static List getControls(Composite c) {
		if(c != null && !c.isDisposed()) {
			List l = new ArrayList();
			l.add(c);
			Control[] a = c.getChildren();
			for(int i = 0; i < a.length; i++) {
				if(!a[i].isDisposed()) {
					if(a[i] instanceof Composite) {
						l.addAll(getControls((Composite) a[i]));
					} else {
						l.add(a[i]);
					}
				}
			}
			return l;
		} else {
			return Collections.EMPTY_LIST;
		}
	}
}
